package com.java.jvalidator.framework.config;

import java.util.HashMap;
import java.util.Map;

import com.java.jvalidator.framework.ErrorMsg;
import com.java.jvalidator.framework.ValidationException;
import com.java.jvalidator.framework.ValidationExceptionMsg;
import com.java.jvalidator.framework.validator.AbstractCustomValidator;
import com.java.jvalidator.framework.validator.Validator;

class RuleConfig {
	private Parameters parameter;
	private Validator validator;
	private String errorMsgName;
	private String[] placeHolderValues;
	private Map<String, String> namedPlaceHolder;
	private boolean multiError = true;
	private String targetClassName;
	private String fieldName;

	RuleConfig(String targetClassName, String propertyName, Validator validator, Parameters parameter, String errorMsgName) {
		this.targetClassName = targetClassName;
		this.fieldName = propertyName;
		this.validator = validator;
		this.parameter = parameter;
		this.errorMsgName = errorMsgName;
		this.namedPlaceHolder = new HashMap<String, String>();
	}

	public boolean isMultiError() {
		return this.multiError;
	}

	public void setMultiError(boolean multiError) {
		this.multiError = multiError;
	}

	protected Object clone() {
		RuleConfig clone = new RuleConfig(this.targetClassName, this.fieldName, this.validator, (Parameters) getParameter().clone(), this.errorMsgName);
		return clone;
	}

	public void setTargetClassName(String targetClassName) {
		this.targetClassName = targetClassName;
	}

	public void setFieldName(String fieldName) {
		this.fieldName = fieldName;
	}

	public void setErrorMsgName(String errorMsgName) {
		this.errorMsgName = errorMsgName;
	}

	String getFieldName() {
		return this.fieldName;
	}

	/**
	 * Validate the rule.It will get the validator from ValidatorManager and
	 * process validation. Custom validator will return its own ErrorMsg.
	 * 
	 * @see RuleConfig#getValidator
	 * @param target
	 * @return
	 * @throws ValidationException
	 */
	ErrorMsg validate(Object target) throws ValidationException {
		if (this.validator == null) {
			throw new ValidationException(ValidationExceptionMsg.VALIDATOR_NOT_FOUND_ERROR);
		}
		if ((this.validator instanceof AbstractCustomValidator)) {
			AbstractCustomValidator cutomValidator = (AbstractCustomValidator) this.validator;
			cutomValidator.clearErrorMsg();
		}
		if (!this.validator.validate(target, this.fieldName, this.parameter)) {
			ErrorMsg msg = new ErrorMsg(target, this.fieldName, this.errorMsgName);
			msg.setPlaceHolderValue(this.placeHolderValues);
			msg.setNamedPlaceHolder(this.namedPlaceHolder);
			return msg;
		}
		return null;
	}

	void setNamedPlaceHolder(Map<String, String> namedPlaceHolder) {
		this.namedPlaceHolder = namedPlaceHolder;
	}

	void addParameters(Parameters params) {
		if (params == null) {
			return;
		}
		if (this.parameter == null) {
			this.parameter = new Parameters();
		}
		this.parameter.addParameters(params);
	}

	Validator getValidator() {
		return this.validator;
	}

	void configCustomValidator(Parameters params) {
		if ((this.validator == null) || (!(this.validator instanceof AbstractCustomValidator))) {
			return;
		}
		if (this.parameter == null) {
			this.parameter = new Parameters();
		}
		this.parameter.addParameters(params);
	}

	public String getTargetClassName() {
		return this.targetClassName;
	}

	void setPlaceHolderValues(String[] values) {
		this.placeHolderValues = values;
	}

	String getErrorMsgName() {
		return this.errorMsgName;
	}

	public Parameters getParameter() {
		if (this.parameter == null) {
			this.parameter = new Parameters();
		}
		return this.parameter;
	}

	public void setParameter(Parameters parameter) {
		this.parameter = parameter;
	}
}
